{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table border=\"0\">\n",
    "    <tr>\n",
    "        <td>\n",
    "            <img src=\"https://ictd2016.files.wordpress.com/2016/04/microsoft-research-logo-copy.jpg\" style=\"width 30px;\" />\n",
    "             </td>\n",
    "        <td>\n",
    "            <img src=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2016/12/MSR-ALICE-HeaderGraphic-1920x720_1-800x550.jpg\" style=\"width 100px;\"/></td>\n",
    "        </tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Choosing First Stage Models in EconML Estimators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Choosing first stage models for the various EconML estimators can seem like a daunting task. However, there are several ways to choose suitable first stage models, depending on the problem you are trying to solve. In this notebook, we go through the various types of crossvalidation and hyperparameter tuning used to select the first stage models.   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 1;\n                var nbb_formatted_code = \"import warnings\\n\\nwarnings.filterwarnings(\\\"ignore\\\")\\n\\n# Imports\\nimport numpy as np\\nimport scipy.special\\nfrom econml.dml import LinearDML\\nfrom sklearn.linear_model import Lasso, LassoCV\\nfrom sklearn.ensemble import GradientBoostingRegressor\\nfrom sklearn.model_selection import GridSearchCV\\nfrom sklearn.preprocessing import PolynomialFeatures\\nimport matplotlib.pyplot as plt\\nimport matplotlib\\n\\n%matplotlib inline\\n%load_ext nb_black\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Imports\n",
    "import numpy as np\n",
    "from econml.dml import LinearDML\n",
    "from sklearn.linear_model import Lasso, LassoCV\n",
    "from sklearn.ensemble import GradientBoostingRegressor\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 2;\n                var nbb_formatted_code = \"# Data generation with quadratic treatment effect\\nnp.random.seed(123)\\nn = 2000\\np = 10\\nW = np.random.uniform(size=(n, p))\\nX = np.random.uniform(size=(n, 1))\\ntrue_effect = lambda x: x[:, 0] ** 2\\nT = W[:, 0] + W[:, 1] ** 2 + np.random.uniform(-1, 1, size=n)\\nY = (\\n    true_effect(X) * T\\n    + W @ np.random.uniform(size=p)\\n    + np.random.uniform(-1, 1, size=n)\\n)\\nX_test = np.arange(0, 1, 0.02).reshape(-1, 1)\\ntest_effect = true_effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Data generation with quadratic treatment effect\n",
    "np.random.seed(123)\n",
    "n = 2000\n",
    "p = 10\n",
    "W = np.random.uniform(size=(n, p))\n",
    "X = np.random.uniform(size=(n, 1))\n",
    "def true_effect(x):\n",
    "    return x[:, 0] ** 2\n",
    "T = W[:, 0] + W[:, 1] ** 2 + np.random.uniform(-1, 1, size=n)\n",
    "Y = (\n",
    "    true_effect(X) * T\n",
    "    + W @ np.random.uniform(size=p)\n",
    "    + np.random.uniform(-1, 1, size=n)\n",
    ")\n",
    "X_test = np.arange(0, 1, 0.02).reshape(-1, 1)\n",
    "test_effect = true_effect(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Using cross-validated estimators as first stage models\n",
    "\n",
    "The most straightforward way to choose a first stage model is to not choose one at all and instead let the EconML estimators do the work for you. To achieve this, you can pass in a cross-validated estimator such as `sklearn`'s `LassoCV` or `GridSearchCV` as the first stage models. The EconML estimator will internally run the cross-validation step and select the best models for the first stage. \n",
    "\n",
    "**Advantages:** \n",
    "\n",
    "* Requires little to no boilerplate code, you can just pass in a CV estimator along with a hyperparameter grid.\n",
    "\n",
    "**Disadvantages:**\n",
    "\n",
    " * The EconML estimator will take longer to run due to an internal cross-validation step for computing the residuals. Further, the CV estimator will be trained on $n_{samples}/\\text{cv}$ data points which might not be suitable for small datasets. \n",
    " * Requires special CV estimator to choose among many classes of estimators (e.g. Lasso and GradientBoostingForest, see section 2.2. for workaround)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 3;\n                var nbb_formatted_code = \"model_y = LassoCV(max_iter=10000)\\nmodel_t = LassoCV(max_iter=10000)\\nest = LinearDML(\\n    model_y=model_y,\\n    model_t=model_t,\\n    featurizer=PolynomialFeatures(degree=2),\\n    fit_cate_intercept=False,\\n)\\nest.fit(Y, T, X=X, W=W)\\nte_pred_lasso = est.effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model_y = LassoCV(max_iter=10000)\n",
    "model_t = LassoCV(max_iter=10000)\n",
    "est = LinearDML(\n",
    "    model_y=model_y,\n",
    "    model_t=model_t,\n",
    "    featurizer=PolynomialFeatures(degree=2),\n",
    "    fit_cate_intercept=False,\n",
    ")\n",
    "est.fit(Y, T, X=X, W=W)\n",
    "te_pred_lasso = est.effect(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 4;\n                var nbb_formatted_code = \"first_stage = lambda: GridSearchCV(\\n    estimator=GradientBoostingRegressor(),\\n    param_grid={\\\"max_depth\\\": [3, 5, None], \\\"n_estimators\\\": (50, 100, 200)},\\n    cv=2,\\n    n_jobs=-1,\\n)\\nest = LinearDML(\\n    model_y=first_stage(),\\n    model_t=first_stage(),\\n    featurizer=PolynomialFeatures(degree=2),\\n    linear_first_stages=False,\\n)\\nest.fit(Y, T, X=X, W=W)\\nte_pred_gbr = est.effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def first_stage():\n",
    "    return GridSearchCV(estimator=GradientBoostingRegressor(), param_grid={\"max_depth\": [3, 5, None],\n",
    "                                                                           \"n_estimators\": (50, 100, 200)},\n",
    "                        cv=2, n_jobs=-1)\n",
    "est = LinearDML(\n",
    "    model_y=first_stage(),\n",
    "    model_t=first_stage(),\n",
    "    featurizer=PolynomialFeatures(degree=2)\n",
    ")\n",
    "est.fit(Y, T, X=X, W=W)\n",
    "te_pred_gbr = est.effect(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 5;\n                var nbb_formatted_code = \"plt.plot(X_test, test_effect, \\\"--\\\", label=\\\"Truth\\\")\\nplt.plot(X_test, te_pred_lasso, label=\\\"DML with LassoCV\\\")\\nplt.plot(X_test, te_pred_gbr, label=\\\"DML with GradientBoostingRegressor\\\")\\nplt.legend()\\nplt.xlabel(\\\"X\\\")\\nplt.ylabel(\\\"Effect\\\")\\nplt.show()\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test, test_effect, \"--\", label=\"Truth\")\n",
    "plt.plot(X_test, te_pred_lasso, label=\"DML with LassoCV\")\n",
    "plt.plot(X_test, te_pred_gbr, label=\"DML with GradientBoostingRegressor\")\n",
    "plt.legend()\n",
    "plt.xlabel(\"X\")\n",
    "plt.ylabel(\"Effect\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Performing first stage model selection outside of EconML\n",
    "\n",
    "An alternative to passing in CV models to EconML is to perform model selection outside of the EconML estimators and then pass in the pre-selected models to EconML. This is the preferred method for first stage model selection due to its statistical and computational advantages.\n",
    "\n",
    "**Advantages:** \n",
    "\n",
    "* Faster runtimes of the EconML estimators and more flexible selection of first stage models.\n",
    "\n",
    "* As long as $\\log(\\text{#hyperparameters}) << O(n_{samples})$, this approach maintains statisical validity of the resulting inference results.\n",
    "\n",
    "**Disadvantages:** Requires more boilerplate code and manual training, scoring and selection of the first stage models."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1. Tuning hyperparameters within the same estimator class\n",
    "\n",
    "Here we select the best estimator within a given class (e.g. Lasso or GradientBoostingForest). This is done by conventional hyperparameter tuning. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 6;\n                var nbb_formatted_code = \"XW = np.hstack([X, W])\\nmodel_y_alpha = LassoCV(max_iter=10000).fit(XW, Y).alpha_\\nmodel_t_alpha = LassoCV(max_iter=10000).fit(XW, T).alpha_\\nmodel_y = Lasso(alpha=model_y_alpha, max_iter=10000)\\nmodel_t = Lasso(alpha=model_t_alpha, max_iter=10000)\\nest = LinearDML(\\n    model_y=model_y,\\n    model_t=model_t,\\n    featurizer=PolynomialFeatures(degree=2),\\n    fit_cate_intercept=False,\\n)\\nest.fit(Y, T, X=X, W=W)\\nte_pred_lasso = est.effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "XW = np.hstack([X, W])\n",
    "model_y_alpha = LassoCV(max_iter=10000).fit(XW, Y).alpha_\n",
    "model_t_alpha = LassoCV(max_iter=10000).fit(XW, T).alpha_\n",
    "model_y = Lasso(alpha=model_y_alpha, max_iter=10000)\n",
    "model_t = Lasso(alpha=model_t_alpha, max_iter=10000)\n",
    "est = LinearDML(\n",
    "    model_y=model_y,\n",
    "    model_t=model_t,\n",
    "    featurizer=PolynomialFeatures(degree=2),\n",
    "    fit_cate_intercept=False,\n",
    ")\n",
    "est.fit(Y, T, X=X, W=W)\n",
    "te_pred_lasso = est.effect(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 7;\n                var nbb_formatted_code = \"model_y = first_stage().fit(XW, Y).best_estimator_\\nmodel_t = first_stage().fit(XW, T).best_estimator_\\nest = LinearDML(\\n    model_y=model_y,\\n    model_t=model_t,\\n    featurizer=PolynomialFeatures(degree=2),\\n    linear_first_stages=False,\\n)\\nest.fit(Y, T, X=X, W=W)\\nte_pred_gbr = est.effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model_y = first_stage().fit(XW, Y).best_estimator_\n",
    "model_t = first_stage().fit(XW, T).best_estimator_\n",
    "est = LinearDML(\n",
    "    model_y=model_y,\n",
    "    model_t=model_t,\n",
    "    featurizer=PolynomialFeatures(degree=2)\n",
    ")\n",
    "est.fit(Y, T, X=X, W=W)\n",
    "te_pred_gbr = est.effect(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 8;\n                var nbb_formatted_code = \"plt.plot(X_test, test_effect, \\\"--\\\", label=\\\"Truth\\\")\\nplt.plot(X_test, te_pred_lasso, label=\\\"DML with LassoCV\\\")\\nplt.plot(X_test, te_pred_gbr, label=\\\"DML with GradientBoostingRegressor\\\")\\nplt.legend()\\nplt.xlabel(\\\"X\\\")\\nplt.ylabel(\\\"Effect\\\")\\nplt.show()\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test, test_effect, \"--\", label=\"Truth\")\n",
    "plt.plot(X_test, te_pred_lasso, label=\"DML with LassoCV\")\n",
    "plt.plot(X_test, te_pred_gbr, label=\"DML with GradientBoostingRegressor\")\n",
    "plt.legend()\n",
    "plt.xlabel(\"X\")\n",
    "plt.ylabel(\"Effect\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2. Choosing amongst different classes of estimators\n",
    "\n",
    "Here we select among different classes of estimators. This is essentially a two-step process where we first do in-class parameter tuning and then we choose among the optimized models. EconML offers the `GridSearchCVList` utility class to perform this type of model selection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 9;\n                var nbb_formatted_code = \"from econml.sklearn_extensions.model_selection import GridSearchCVList\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from econml.sklearn_extensions.model_selection import GridSearchCVList"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 10;\n                var nbb_formatted_code = \"first_stage = lambda: GridSearchCVList(\\n    [Lasso(max_iter=10000), GradientBoostingRegressor()],\\n    param_grid_list=[\\n        {\\\"alpha\\\": [0.001, 0.01, 0.1, 1, 10]},\\n        {\\\"max_depth\\\": [3, 5, None], \\\"n_estimators\\\": [50, 100, 200]},\\n    ],\\n    cv=2,\\n)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def first_stage():\n",
    "    return GridSearchCVList([Lasso(max_iter=10000), GradientBoostingRegressor()],\n",
    "                            param_grid_list=[{\"alpha\": [0.001, 0.01, 0.1, 1, 10]},\n",
    "                                             {\"max_depth\": [3, 5, None],\n",
    "                                              \"n_estimators\": [50, 100, 200]}],\n",
    "                            cv=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 11;\n                var nbb_formatted_code = \"model_y = first_stage().fit(XW, Y).best_estimator_\\nmodel_t = first_stage().fit(XW, T).best_estimator_\\nest = LinearDML(\\n    model_y=model_y, model_t=model_t, featurizer=PolynomialFeatures(degree=2)\\n)\\nest.fit(Y, T, X=X, W=W)\\nte_pred = est.effect(X_test)\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model_y = first_stage().fit(XW, Y).best_estimator_\n",
    "model_t = first_stage().fit(XW, T).best_estimator_\n",
    "est = LinearDML(\n",
    "    model_y=model_y, model_t=model_t, featurizer=PolynomialFeatures(degree=2)\n",
    ")\n",
    "est.fit(Y, T, X=X, W=W)\n",
    "te_pred = est.effect(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "\n            setTimeout(function() {\n                var nbb_cell_id = 12;\n                var nbb_formatted_code = \"plt.plot(X_test, test_effect, \\\"--\\\", label=\\\"Truth\\\")\\nplt.plot(X_test, te_pred, label=\\\"DML with GridSearchCVList\\\")\\nplt.legend()\\nplt.xlabel(\\\"X\\\")\\nplt.ylabel(\\\"Effect\\\")\\nplt.show()\";\n                var nbb_cells = Jupyter.notebook.get_cells();\n                for (var i = 0; i < nbb_cells.length; ++i) {\n                    if (nbb_cells[i].input_prompt_number == nbb_cell_id) {\n                        nbb_cells[i].set_text(nbb_formatted_code);\n                        break;\n                    }\n                }\n            }, 500);\n            ",
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test, test_effect, \"--\", label=\"Truth\")\n",
    "plt.plot(X_test, te_pred, label=\"DML with GridSearchCVList\")\n",
    "plt.legend()\n",
    "plt.xlabel(\"X\")\n",
    "plt.ylabel(\"Effect\")\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
